#ifndef _CMD_C_
#define _CMD_C_

#include	"config.h"
#include <stdio.h>

u8 CMD_Head, CMD_End;
u8 CMD_Buffer[CMD_FIFO_LEN][CMD_LINE_BUF];

static s16 SP_Help(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 SP_Switch2Car(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 SP_Switch2Box(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 SP_SendKey(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);


static s16 SP_Poweroff(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 SP_RST_A6(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 cantx(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 SP_NavCom(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 SP_NavHand(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 SP_Dash(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

static s16 SP_AUX(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param);

//static s16 SP_SoftRstTW8825(u16 argc, char* argv[],
//			SHELL_OUT_FNCT out_fnct,
//			SHELL_CMD_PARAM *pcmd_param);


u32 str2int(char* str);

static SHELL_CMD APP_ShellCmdTbl[] = 
{
	{"sp_h",SP_Help},
	{"sp_car", SP_Switch2Car},
	{"sp_box", SP_Switch2Box},
	{"sp_key", SP_SendKey},
	{"sp_off", SP_Poweroff},
	{"sp_rst", SP_RST_A6},
	{"sp_cantx", cantx},
	{"sp_navcom", SP_NavCom},
	{"sp_navhand", SP_NavHand},
	{"sp_dash", SP_Dash},
    {"sp_aux",SP_AUX},
//    {"sp_softrst",SP_SoftRstTW8825},
	{0,0},
};

s16 APP_ShellOut(char* pbuf, u16 len, void* popt)
{
	if (len<256)
	{
		Trace(pbuf);
		Trace("\r\n");
		return 1;
	}
	return 0;
}



static s16 SP_AUX(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
    u32 tmp1;
	tmp1 = str2int(argv[1]);
    if (tmp1)
    {
        doSwitchToAux();
    }
    else
    {
        cancelSwitchToAux();
    }
    
    return 0;
}

static s16 SP_Help(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	Trace("sp_h: help\r\n");
	Trace("sp_car: switch sp to car\r\n");
	Trace("sp_box: switch sp to box\r\n");
	Trace("sp_off: power off\r\n");
	Trace("sp_rst: reset A6\r\n");
	Trace("sp_cantx: can tx\r\n");
	Trace("sp_navcom: 1: debug comm on;  0 debug comm off\r\n");
	Trace("sp_navhand: 1: debug handwrite on;  0 debug handwrite off\r\n");
    Trace("sp_dash: tw8825 init 1  2  3\r\n");
    Trace("sp_aux: Switch aux\r\n");
    
	return 0;
}

static s16 SP_Switch2Car(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	ipcStartEvent(EVENT_GLOBAL_VIDEO_SWITCH,CarDisplay,0,0);
	return 0;
}

static s16 SP_Switch2Box(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	ipcStartEvent(EVENT_GLOBAL_VIDEO_SWITCH,ARMDisplay,0,0);
	return 0;
}

static s16 SP_SendKey(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	static const u8 testkey[] = { 	0
//                                    SINO_KEY_ENTER,  //0
//									SINO_KEY_BACK,// 1
//									SINO_KEY_LEFT,// 2
//									SINO_KEY_RIGHT,// 3
//									SINO_KEY_UP, // 4
//									SINO_KEY_DOWN,// 5
//									SINO_KEY_LEFT_ROLL,// 6
//									SINO_KEY_RIGHT_ROLL,// 7
//									SINO_KEY_ZOOM_IN,//8 
//									SINO_KEY_ZOOM_OUT// 9
									};
	
	u32 tmp1, tmp2;
	tmp1 = str2int(argv[1]);
	tmp2 = str2int(argv[2]);
	if (tmp1)
	{
		ipcStartEvent(EVENT_GLOBAL_NAVI_PANEL_KEY_PRESSED,testkey[tmp2],NULL,NULL); //send to box; 
	}
	else
	{
		//ipcStartEvent(EVENT_GLOBAL_AUTO_KEY_TEST,testmmikey[tmp2],NULL,NULL);   // send to car  tmp2 = [0~14]
	}
	return 0;
}

static s16 SP_Dash(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	u32 tmp;
	tmp = str2int(argv[1]); 
    switch (tmp)
    {
        case 1:
            sendTestDisplay1();
            break;
        case 2:
			sendTestDisplay2();
            break;
        case 3:
			sendTestDisplay3();
            break;
		case 4:
			sendTestDisplay4();
			break;
		case 5:
			sendTestDisplay5();
		break;
        default:
            Trace("Select 1  2  3  4  5\r\n");
            break;
    }
    return 0;
}

//static s16 SP_SoftRstTW8825(u16 argc, char* argv[],
//			SHELL_OUT_FNCT out_fnct,
//			SHELL_CMD_PARAM *pcmd_param)

//{
////    u8 tmp;
////    TW8825_IICWriteByte(0xff,0x00);
////	tmp = TW8825_IICReadByte(0x06);
////    TW8825_IICWriteByte(0x06,tmp|0x80);
//    return 0;
//}

static s16 SP_NavCom(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	u32 tmp;
	tmp = str2int(argv[1]);
	if (tmp)
	{
		naviBoardInfo.naviDebugComm = TRUE;
	}
	else
	{
		naviBoardInfo.naviDebugComm = FALSE;
	}
	return 0;
}

static s16 SP_NavHand(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	u32 tmp;
	tmp = str2int(argv[1]);
	if (tmp)
	{
		naviBoardInfo.naviDebugHandwrite = TRUE;
	}
	else
	{
		naviBoardInfo.naviDebugHandwrite = FALSE;
	}
	return 0;
}


static s16 SP_Poweroff(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	CAN0_ModuleWork(FALSE);
	return 0;
}

static s16 SP_RST_A6(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	ARM_RESET_HIGH;
	DelayTimer(200);
	ARM_RESET_LOW;
	DelayTimer(200);
	ARM_RESET_HIGH;
    naviBoardInfo.naviBoardInit = FALSE;
	DelayTimer(200);
	naviBoardInfo.lastNaviPingMessageTime = GetTickCount();
    //MAX9259_Init();
	return 0;
}

static s16 cantx(u16 argc, char* argv[],
			SHELL_OUT_FNCT out_fnct,
			SHELL_CMD_PARAM *pcmd_param)
{
	CanTxMsg msg1 = {0xFB, 0xFB, CAN_ID_STD,CAN_RTR_DATA, 0x08, 0xFF, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x03};
    CanTxMsg msg2 = {0x1BB, 0x1BB, CAN_ID_STD,CAN_RTR_DATA, 0x08, 0xFF, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x03};
    
	CAN_Transmit(CAN1,&msg1);
	CAN_Transmit(CAN2,&msg2);	
	
	return 0;
}

u32 str2int(char* str)
{
	u32 value = 0;
	u8 radix;
	if(*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
	{
		radix = 16;
		str += 2;
	}
	else
	{
		radix = 10;	
	}
	
	while( (*str >= '0' && *str <= '9') ||
		   (*str >= 'a' && *str <= 'f') ||
		   (*str >= 'A' && *str <= 'F') )
	{
		if(radix == 16)
		{
			if(*str >= '0' && *str <= '9')
			   value = value * radix + *str - '0';
			else
			   value = value * radix + (*str | 0x20) - 'a' + 10;
		}
		else
		{
			value = value * radix + *str - '0';
		}
		str++;
	}
	return value;
}

void CMD_Init(void)
{
	u8 tmp;
	SHELL_ERR err;
	tmp = Shell_Init();
	//printf("\r\nBuild Time: %s, %s.\r\n",__DATE__, __TIME__);
	if (tmp == 1)
	{
		//Trace("CMD init done!\r\n");
	}
	else
	{
		Trace("CMD init failed!\r\n");
		return;
	}
	Shell_CmdTblAdd("sp", APP_ShellCmdTbl, &err);
	if (err == SHELL_ERR_NONE) {
		//Trace("CMD add done.\n\r");
	} else {
		Trace("CMD add failed.\n\r");
	}
}

void CMD_Run(void)
{
	SHELL_ERR err;
	if(CMD_Head != CMD_End)
	{
		Shell_Exec((char*)&CMD_Buffer[CMD_End][0], &APP_ShellOut,0, &err);
		CMD_End = (CMD_End+1)%CMD_FIFO_LEN;
		
		switch (err) 
		{
			case SHELL_ERR_NONE:
				Trace("\r\nCommand executed, no error.\r\n");
			break;
			
			case SHELL_ERR_NULL_PTR:
				Trace("\r\nError, NULL pointer passed.\r\n");
			break;
			
			case SHELL_ERR_CMD_NOT_FOUND:
				Trace("\r\nError, command NOT found.\r\n");
			break;
			
			case SHELL_ERR_CMD_SEARCH:
				Trace("\r\nError, searching command.\r\n");
			break;
			
			case SHELL_ERR_ARG_TBL_FULL:
				Trace("\r\nError, too many arguments.\r\n");
			break;
			
			default:
			break;
		}
	}
}
#endif
